package com.ljx.rpc.core.transport;

import com.ljx.rpc.core.domain.dto.RpcRequest;
import com.ljx.rpc.core.domain.dto.RpcResponse;
import com.ljx.rpc.core.domain.enums.RpcCodeEnum;
import com.ljx.rpc.core.exception.RpcException;
import com.ljx.rpc.core.transport.socket.client.SocketClient;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Objects;

/**
 * @Author: LiJunXi
 * @Description:
 * @Date: 2024-10-07  19:46
 */
public class RpcClientProxy implements InvocationHandler {

    private RpcClient rpcClient;

    public RpcClientProxy(RpcClient rpcClient) {
        this.rpcClient = rpcClient;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        RpcRequest rpcRequest = RpcRequest.builder()
                .interfaceName(method.getDeclaringClass().getName())
                .methodName(method.getName())
                .parameters(args)
                .paramTypes(method.getParameterTypes())
                .build();
        RpcResponse response = null;
        if (rpcClient instanceof SocketClient){
            response = (RpcResponse) rpcClient.sendRequest(rpcRequest);
        }

        if (Objects.isNull(response)){
            throw new RpcException("RPC调用失败");
        }
        if (RpcCodeEnum.FAIL.getKey().equals(response.getCode())){
            throw new RpcException("RPC调用失败，原因：" + response.getData());
        }

        return response.getData();
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> clazz) {
        return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[]{clazz}, this);
    }
}
